package main

import (
	"fmt"
	"net/http"
	"os"
	"sync"
)

var wg sync.WaitGroup

// 一般没有这么用的，http.Server的Handler字段
// 要么是nil，就用包里的http.DefaultServeMux
// 要么用NewServeMux()来创建一个*http.ServeMux
// 我这里按照http.Handler接口的要求实现了一个，赋值给Handler字段
// 这个自定义的Handler不支持路由
func startServer1() {
	defer wg.Done()
	var httpServer http.Server
	httpServer.Addr = "127.0.0.1:8001"
	httpServer.Handler = http.HandlerFunc(
		func(w http.ResponseWriter, r *http.Request) {
			fmt.Println(*r)
			fmt.Fprint(w, "Hello World")
		},
	)
	fmt.Println("启动服务，访问: http://127.0.0.1:8001")
	if err := httpServer.ListenAndServe(); err != nil {
		if err == http.ErrServerClosed {
			fmt.Println("HTTP Server1 Closed.")
		} else {
			fmt.Fprintf(os.Stderr, "HTTP Server1 Error: %v\n", err)
		}
	}
}

// 这个最简单，都是调用http包里的函数。本质上还是要调用方法的，都会用默认的或是零值
func startServer2() {
	defer wg.Done()
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "Hello World\nThis is Server2")
	})
	fmt.Println("启动服务，访问: http://127.0.0.1:8002")
	// 第二个参数传nil，就是用包里的http.DefaultServeMux，或者也可以自己创建一个传给第二个参数
	if err := http.ListenAndServe("127.0.0.1:8002", nil); err != nil {
		if err == http.ErrServerClosed {
			fmt.Println("HTTP Server2 Closed.")
		} else {
			fmt.Fprintf(os.Stderr, "HTTP Server2 Error: %v\n", err)
		}
	}
}

// 这个例子里用到了解析Get请求的参数，并且还设置了2个路由
func startServer3() {
	defer wg.Done()
	mux := http.NewServeMux()
	mux.HandleFunc("/hi", func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path != "/hi" {
			// 这个分支应该是进不来的，因为要进入这个分支，路径应该必须是"/hi"
			fmt.Println("Server3 hi 404")
			http.NotFound(w, r)
			return
		}
		name := r.FormValue("name")
		if name == "" {
			fmt.Fprint(w, "Hi!")
		} else {
			fmt.Fprintf(w, "Hi, %s!", name)
		}
	})
	mux.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "Hello World\nThis is Server3")
	})
	// 如果只是定义http.Server的下面2个字段，完全可以使用http.ListenAndServe函数来启动服务
	// 这样的用法可以对http.Server里更多的字段进行自定义
	httpServer := http.Server{
		Addr: "127.0.0.1:8003",
		Handler: mux,
	}
	fmt.Println("启动服务，访问: http://127.0.0.1:8003/hi?name=Adam")
	if err := httpServer.ListenAndServe(); err != nil {
		if err == http.ErrServerClosed {
			fmt.Println("HTTP Server3 Closed.")
		} else {
			fmt.Fprintf(os.Stderr, "HTTP Server3 Error: %v\n", err)
		}
	}
}

func main() {
	wg.Add(1)
	go startServer1()
	wg.Add(1)
	go startServer2()
	wg.Add(1)
	go startServer3()
	wg.Wait()
}
